/**
 * @addtogroup gbc_msg_17691
 * gbc_17691_ds_interface
 * @brief        数据流编解码接口,对于不同的地标数据流协议，采用统一接口。
 * @par 示例
 * @code
    // 数据流编码接口，在实时消息和补发消息的编码中调用，一般不需要使用者调用
    // 公开此接口的目的，是为了适应各地标数据流的协议，使用者可以通过实现接口来完成对各地标数据流编码

    Int32 ds_len = 0;
    UInt8 buf[1024];    ///< 存放编码的缓存，一般从外部传入，示例这里为了写明白直接定义
    Int32 pos = 0;
    TGbc17691MsgStreamItem stream_item[3];
    Int32 msg_count = sizeof(stream_item)/sizeof(stream_item[0]);
    ...//stream_item对象赋值

    for (i = 0; i < msg_count; i++)
    {
        if (stream_item[i].msg_type == kPt17691MsgTypeObd) ///< OBD数据流编码
        {
            ds_len = IGbc17691EncodeObd(msg_mgr->data_stream_codec, &stream_item[i], buf + pos, buf_size - pos);
        }
        else if (stream_item[i].msg_type == kPt17691MsgTypeDataStream) ///< 发送机数据流编码
        {
            ds_len = IGbc17691EncodeDataStream(msg_mgr->data_stream_codec, &stream_item[i], buf + pos, buf_size - pos);
        }
        pos += ds_len;
    }
 * @endcode
 * @{
 */
/**
 * @file         gbc_17691_ds_interface.h
 * @brief        数据流编解码接口
 * @note
 * @author       Dengdeshou
 * @date         2020-08-06
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-08-06  <td>1.0                   <td>Dengdeshou      <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SCC_PT17691_DS_INTERFACE_H_
#define _SCC_PT17691_DS_INTERFACE_H_

#include "ofc/ofc_object.h"
#include "mfc/mfc_string.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct IGbc17691DataStreamTag IGbc17691DataStream;

/**
 * 信息类型
 */
enum TGbc17691MsgTypeEnumTag
{
    kPt17691MsgTypeObd = 1,                        ///< OBD信息
    kPt17691MsgTypeDataStream = 2,                 ///< 数据流信息
    kPt17691MsgTypeTwcDataStream = 3,              ///< 数据流信息（三元催化）无 NOx 传感器
    kPt17691MsgTypeHybridDataStream = 4,           ///< 混动车附加
    kPt17691MsgTypeTwcWithNOxDataStream = 5,       ///< 数据流信息（三元催化）有 NOx 传感器
    kPt17691MsgTypeDataStreamReplenish = 0x80,     ///< 补充数据流
};
typedef enum TGbc17691MsgTypeEnumTag TGbc17691MsgTypeEnum;

/**
 * 数据流类型
 */
enum TGbc17691StreamTypeEnumTag
{
    kPt17691StreamTypeBinary = 0,                ///< 数据流以二进制流形式提供
    kPt17691StreamTypeObject = 1,                ///< 数据流以对象形式提供
};
typedef enum TGbc17691StreamTypeEnumTag TGbc17691StreamTypeEnum;

/**
 * 单条信息流
 */
typedef struct TGbc17691MsgStreamItemTag TGbc17691MsgStreamItem;
struct TGbc17691MsgStreamItemTag
{
    UInt8 msg_type;                     ///< 信息类型,参考TGbc17691MsgTypeEnum
    UInt16 msg_seq;                     ///< 信息流水号
    UInt8 collect_time[6];              ///< 采集时间
    UInt8 msg_stream_object_type;       ///< 数据流类型
    Int32 msg_stream_len;               ///< 数据流的长度
    void *msg_stream;                   ///< 数据流的结构体指针
};

typedef struct TGbc17691EngineStreamTag TGbc17691EngineStream;
struct TGbc17691EngineStreamTag
{
    UInt16 speed;              ///< 车速，精度：1/256 km/h per bit 数据范围：0 ~ 250.996 km/h “0xFF,0xFF”表示无效
    UInt8  air_pressure;       ///< 大气压力 0.5 kPa/bit 数据范围：0 ~ 125 kPa “0xFF”表示无效
    UInt8  engine_torque;      ///< 发动机输出扭矩 1%/bit 偏移量：-125 数据范围：-125 ~ 125 % “0xFF”表示无效
    UInt8  friction_torque;    ///< 摩擦扭矩 精度：1%/bit 偏移量：-125 数据范围：-125 ~ 125 % “0xFF”表示无效
    UInt16 revolution;         ///< 发动机转速 0.125rpm/bit 偏移量：0 数据范围：0 ~ 8031.875 rpm “0xFF,0xFF”表示无效
    UInt16 fuel_flow;          ///< 发动机燃料流量 精度：0.05L/h 偏移量：0 数据范围：0 ~ 3212.75L/h “0xFF,0xFF”表示无效
    UInt16 src_nox_upper;      ///< SCR上游NOx传感器输出值 精度：0.05ppm/bit 偏移量：-200 数据范围：-200 ~ 3012.75ppm
    UInt16 scr_nox_downer;     ///< scr下游NOx传感器输出值 精度：0.05ppm/bit 偏移量：-200 数据范围：-200 ~ 3012.75ppm
    UInt8  reactant_allowance; ///< 反应剂余量 精度：0.4%/bit 数据范围：0 ~ 100 %
    UInt16 air_quality_intake; ///< 空气质量流量传感器读取的进气量 精度：0.05kg/h per bit 数据范围：0 ~ 3212.75 kg/h“0xFF,0xFF”表示无效
    UInt16 scr_entrance_temp;  ///< SCR入口温度 精度：0.03125deg C/bit 偏移量：-273 数据范围：-273 ~ 1734.96875deg C “0xFF,0xFF”表示无效
    UInt16 scr_exit_temp;      ///< SCR出口温度 精度：0.03125deg C/bit 偏移量：-273 数据范围：-273 ~ 1734.96875deg C “0xFF,0xFF”表示无效
    UInt16 dpf_pressure_diff;  ///< DPF压差 精度：0.1kPa/bit 偏移量：0 数据范围：0 ~ 6425.5 kPa “0xFF,0xFF”表示无效
    UInt8  coolant_temp;       ///< 发动机冷却液温度        精度：1deg C/bit    移量：-40 数据范围：-40 ~ 210 deg C “0xFF”表示无效
    UInt8  mailbox_level;      ///< 油箱液位 精度：0.4%/bit 偏移量：0 数据范围：0 ~ 100 % “0xFF”表示无效
    UInt8  loact_status;       ///< 定位状态 bit0 0:有效定位；1:无效定位 bit1 0:北纬；1:南纬。bit2 0:东经；1:西经。
    UInt32   longitude;        ///< 经度 精度：0.000001°/bit 偏移量：0 数据范围：0 ~ 180.000000° “0xFF，0xFF，0xFF，0xFF”表示无效
    UInt32   latitdue;         ///< 纬度 精度：0.000001°/bit 偏移量：0 数据范围：0 ~ 90.000000 ° “0xFF，0xFF，0xFF，0xFF”表示无效
    UInt32   odo;              ///< 累计里程 精度：0.1km/bit 偏移量：0 “0xFF，0xFF，0xFF，0xFF”表示无效
    UInt8   engine_max_torque;           ///< 发动机最大基准扭矩 1%/bit 偏移量：-125 数据范围：-125 ~ 125 % “0xFF”表示无效
    UInt16  twc_downer;                  ///< 三元催化下游NoX传感器输出 精度：0.05ppm /bit 偏移量： -200 数据范围：-200~3212.75ppm “0xFF， 0xFF”表示无效
    UInt16  front_oxygen_sensor;         ///< 前氧传感器输出 偏移量：0 “0xFF， 0xFF”表示无效
    UInt16  back_oxygen_sensor;          ///< 后氧传感器输出 偏移量：0 “0xFF， 0xFF”表示无效
    UInt16  before_exhaust_temp;         ///< 排气前温度 精度： 0.03125℃ /bit 偏移量： -273 数据范围： -273~1734.96875℃ “0xFF， 0xFF”表示无效
    UInt16  after_exhaust_temp;          ///< 排气后温度 精度：0.03125℃ /bit 偏移量：-273 数据范围：-273~1734.96875℃ “0xFF， 0xFF”表示无效
    UInt8   absorption_coefficient;      ///< 光吸收系数 精度：0.4% /bit 偏移量：0 数据范围： 0~100% “0xFF”表示无效
    UInt16  twc_upper_oxygen_sensor;     ///< 三元催化器上游传感器输出 偏移量：0 “0xFF， 0xFF”表示无效
    UInt8   twc_downer_oxygen_sensor;    ///< 三元催化器下游传感器输出 偏移量：0 “0xFF， 0xFF”表示无效
    UInt16  twc_sensor_temp;   ///< 三元催化器温度传感器输出 精度：0.03125 deg C/bit 偏移量：-273 deg C 数据范围：-273～1734.96875 deg C“0xFF，0xFF”表示无效
    
    UInt16 motor_speed;         ///< 电机转速 数据长度：2 byte 精度：1 rpm/bit 偏移量：0 数据范围:0〜65535 “OxFF，OxFF”表示无效
    UInt8 motor_load_perc;      ///< 电机负荷百分比  数据长度：1 byte 精度：1%/bit 偏移量：0% 数据范围:0〜100 “OxFF”表示无效
    UInt16 battery_voltage;     ///< 电池电压  数据长度：2 byte 精度：0.1V/bit 偏移量：0V 数据范围:0〜6553.4 “OxFF，OxFF”表示无效
    UInt16 battery_current;     ///< 电池电流  数据长度：2 byte 精度：0.1A/bit 偏移量：-l000A 数据范围:-1000A〜#53.4A “OxFF，OxFF”表示无效
    UInt8  soc;                 ///< 荷电状态（SOC)  数据长度：1 byte 精度：1%/bit 偏移量：-0% 数据范围:0〜100 “OxFF”表示无效

};

typedef union TGbc17691MonritorStatusTag TGbc17691MonritorStatus;
union TGbc17691MonritorStatusTag
{
    struct TBits
    {
        // 每一位的含义：0=不支持；1=支持
        UInt16 catalyst_monitoring_status : 1;                      ///< 催化剂监控
        UInt16 heated_catalyst_monitoring_status : 1;               ///< 加热催化剂监控
        UInt16 evaporative_system_monitor_status : 1;               ///< 蒸发系统监控
        UInt16 secondary_air_system_monitor_status : 1;             ///< 二次空气系统监控
        UInt16 ac_system_refrigerant_monitor_status : 1;            ///< AC系统制冷剂监控
        UInt16 exhaust_gas_sensor_monitor_status : 1;               ///< 排气传感器器监控
        UInt16 exhaust_gas_sensor_heater_monitor_status : 1;        ///< 排气传感器加热器监控
        UInt16 erg_vvt_system_monitor : 1;                          ///< EGR系统和VVT 监控
        UInt16 cold_start_aid_system_monitor_status : 1;            ///< 冷启动辅助系统监控
        UInt16 boost_perss_conteol_system_monitor_status : 1;       ///< 增压压力控制系统
        UInt16 diesel_particulate_filter_status : 1;                ///< DPF 监控
        UInt16 nox_convert_catelyst_mox_adsorber_monitor_status : 1; ///< 选择性催化还原系统（SCR）或 NOx吸附器
        UInt16 nmhc_convert_catalyst_monitoring_status : 1;         ///< NMHC氧化催化器监控
        UInt16 misfire_monitor_support : 1;                         ///< 失火监控
        UInt16 fuel_system_monitor_support : 1;                     ///< 燃油系统监控
        UInt16 comprehensive_component_monitor_support : 1;         ///< 综合成分监控
    }b;

    UInt16 status;
};

typedef struct TGbc17691ObdMessageTag TGbc17691ObdMessage;
struct TGbc17691ObdMessageTag
{
    UInt8   odb_protocol;                    ///< OBD诊断协议 有效范围0~2，“0”代表ISO15765，“1”代表ISO27145，“2”代表SAEJ1939，“0xFE”表示无效。
    UInt8   mil_status;                      ///< MIL状态 有效范围0~1，“0”代表未点亮，“1”代表点亮，“0xFE”表示无效。
    TGbc17691MonritorStatus monritor_support_status; ///< 诊断支持状态
    TGbc17691MonritorStatus monritor_ready_status;   ///< 诊断就绪状态
    Int8    vin[17];                         ///< 车辆识别码
    Int8    calid[18];                       ///< 校准标识符 软件标定识别号由生产企业自定义，字母或数字组成，不足后面补字符“0”。
    Int8    cvn[18];                         ///< 标定验证码 标定验证码由生产企业自定义，字母或数字组成，不足后面补字符“0”。
    UInt8   iupr[36];                        ///< IUPR值 精度：0.4%/bit 偏移量：0 数据范围：0 ~ 100 % “0xFF”表示无效
    UInt8   fault_count;                     ///< 故障码总数
    UInt32  *fault_code;                     ///< 故障码
};

/**
 * 补充数据流
 */
typedef struct TGbc17691ExtDataTag TGbc17691ExtData;
struct TGbc17691ExtDataTag
{
    // 发动机扭矩模式
    UInt8   engine_torque_mode_;
    // 油门踏板
    UInt8   oil_pedal_;
    // 累计油耗
    UInt32    cumulative_fuel_consumption_;
    // 尿素箱温度
    UInt8   urea_tank_temp_;
    // 实际尿素喷射量
    UInt32    actual_urea_injection_;
    // 累计尿素消耗
    UInt32    cumulative_urea_consumption_;
    // DPF排气温度
    UInt16  dpf_exhaust_temp_;
    // 瞬时油耗
    UInt16    inst_fuel_consumption_;
    // 发动机总运行时间
    UInt32    engine_total_runtime_;
};

/**
 * 数据流编码接口
 * @param sender: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoEncodeDataStream)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);

/**
 * 补充数据流编码接口
 * @param sender: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoEncodeReplenishStream)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);

/**
 * OBD信息编码接口
 * @param sender: 对象指针
 * @param stream_item: OBD数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoEncodeObd)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);


/**
 * 数据流解码接口
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoDecodeDataStream)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * OBD信息解码接口
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoDecodeObd)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * 补充数据流解码接口
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoDecodeReplenishStream)(IGbc17691DataStream *sender, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * 数据流开头部分编码
 * @param sender: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param enc_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据编码后的长度，负数为错误码
 */
typedef Int32(*IGbc17691DoEncodeStreamHead)(IGbc17691DataStream *sender, UInt8 *date_time, UInt8 date_time_len,
    UInt16 msg_seq, UInt8 *enc_buf, Int32 buf_size);

/**
 * 数据流编解码接口
 */
struct IGbc17691DataStreamTag
{
PROTECTED
    IGbc17691DoEncodeDataStream DoEncodeDataStream;             ///< 数据流信息编码
    IGbc17691DoEncodeObd DoEncodeObd;                           ///< OBD信息编码
    IGbc17691DoEncodeReplenishStream DoEncodeReplenishStream;   ///< 补充数据流信息编码
    IGbc17691DoDecodeDataStream DoDecodeDataStream;             ///< 数据流信息解码
    IGbc17691DoDecodeObd DoDecodeObd;                           ///< OBD信息解码
    IGbc17691DoDecodeReplenishStream DoDecodeReplenishStream;   ///< 补充数据流信息解码
    IGbc17691DoEncodeStreamHead DoEncodeStreamHead;             ///< 数据流头部编码
};

/**
 * 数据流编码
 * @param sender: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
Int32 IGbc17691EncodeDataStream(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);

/**
 * 补充数据流编码
 * @param sender: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
Int32 IGbc17691EncodeReplenishStream(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);

/**
 * OBD信息编码接口
 * @param sender: 对象指针
 * @param stream_item: OBD数据流的对象指针
 * @param enc_buf: 存放编码后数据流缓冲，不包含消息头和校验码
 * @param buf_size: 存放编码后缓冲区大小
 * @return 数据流编码后的长度，负数为错误码
 */
Int32 IGbc17691EncodeObd(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *enc_buf, Int32 buf_size);

/**
 * 数据流解码
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
Int32 IGbc17691DecodeDataStream(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * 补充数据流解码
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
Int32 IGbc17691DecodeReplenishStream(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * OBD信息解码接口
 * @param sender: 对象指针
 * @param stream_item: 存放解码后数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据解编码后的长度，负数为错误码
 */
Int32 IGbc17691DecodeObd(IGbc17691DataStream *self, TGbc17691MsgStreamItem *stream_item, UInt8 *dec_buf, Int32 buf_size);

/**
 * 数据流开头部分编码
 * @param self: 对象指针
 * @param stream_item: 数据流的对象指针
 * @param dec_buf: 需要解码的数据流缓冲，不包含消息头和校验码
 * @param buf_size: 缓冲区大小
 * @return 数据编码后的长度，负数为错误码
 */
Int32 IGbc17691EncodeStreamHead(IGbc17691DataStream *self, UInt8 *date_time, UInt8 date_time_len, 
    UInt16 msg_seq, UInt8 *enc_buf, Int32 buf_size);

#ifdef __cplusplus
}
#endif
#endif

/**
 * @} 
 */
